﻿using System;
using System.Collections.Generic;
using System.Numerics;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace IOP.OpenType
{
    /// <summary>
    /// 包围盒转换器
    /// </summary>
    public class BoundingConverter : JsonConverterFactory
    {
        /// <summary>
        /// 是否允许转换
        /// </summary>
        /// <param name="typeToConvert"></param>
        /// <returns></returns>
        public override bool CanConvert(Type typeToConvert)
        {
            if (typeToConvert != typeof(Bounding)) return false;
            return true;
        }

        /// <summary>
        /// 创建转换器
        /// </summary>
        /// <param name="typeToConvert"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
        {
            JsonConverter converter = (JsonConverter)Activator.CreateInstance(typeof(BoundingConverterInner),
                BindingFlags.Instance | BindingFlags.Public,
                binder: null,
                args: new object[] { options },
                culture: null);
            return converter;
        }
    }

    /// <summary>
    /// 包围盒转换器
    /// </summary>
    public class BoundingConverterInner : JsonConverter<Bounding>
    {
        /// <summary>
        /// 配置
        /// </summary>
        public JsonSerializerOptions Options { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="options"></param>
        public BoundingConverterInner(JsonSerializerOptions options)
        {
            Options = options;
        }

        /// <summary>
        /// 读出
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="typeToConvert"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public override Bounding Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            try
            {
                if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("must be startArray first");
                reader.Read();
                float xMin = reader.GetSingle();
                reader.Read();
                float xMax = reader.GetSingle();
                reader.Read();
                float yMin = reader.GetSingle();
                reader.Read();
                float yMax = reader.GetSingle();
                reader.Read();
                return new Bounding(xMin, xMax, yMin, yMax);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 写入
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public override void Write(Utf8JsonWriter writer, Bounding value, JsonSerializerOptions options)
        {
            writer.WriteStartArray();
            writer.WriteNumberValue(value.XMin);
            writer.WriteNumberValue(value.XMax);
            writer.WriteNumberValue(value.YMin);
            writer.WriteNumberValue(value.YMax);
            writer.WriteEndArray();
        }
    }
}
